﻿/**
 * SlotDuino
 * 
 * Copyright (c) 2011/2012 Thiago Hummel Moreira, Ricardo Mizuuti, Rafael Mufato, Bruno Sakai, Andre Turina
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using SlotDaemon.Sockets;

namespace SlotDaemon
{
    public class Program
    {
        public static void Main()
        {
            /*ShiftRegister register = new ShiftRegister(1, Pins.GPIO_PIN_D10, Pins.GPIO_PIN_D13, Pins.GPIO_PIN_D11, ShiftRegister.BitOrder.LSBFirst);
            byte[] buf = new byte[1];
            for (byte i = 0; i < 100; i++)
            {
                buf[0] = (byte)(1 << (i % 8));
                Debug.Print("Byte: " + buf[0]);
                register.Write(buf);
                Thread.Sleep(1000);
            }*/
            
            
            /*var cfg = new SPI.Configuration(
                ChipSelect_Port: Cpu.Pin.GPIO_Pin10,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 1000,
                SPI_mod: SPI.SPI_module.SPI1
            );
            SPI _bus = new SPI(cfg);

            byte[] buf = new byte[1];
            for (byte i = 0; i < 100; i++)
            {
                buf[0] = (byte)(1 << (i % 8));
                Debug.Print("Byte: " + buf[0]);
                _bus.Config = cfg;
                _bus.Write(buf);
                Thread.Sleep(1000);
            }*/

            /*VoltageController vc = new VoltageController(3, 4);

            Lane lane1 = new Lane(1, Cpu.Pin.GPIO_Pin1);
            lane1.VoltageId = 1;
            lane1.OnBeforeVoltageChange += new BeforeVoltageChangeEventHandler(vc.ChangeLaneVoltage);


            Race race1 = new Race(1, TimeSpan.MaxValue, new byte[]{1});
            race1.OnRaceStateChanged += new RaceStateChangedEventHandler(lane1.RaceStateChanged);
            race1.Start();

            Thread.Sleep(2000);
            lane1.VoltageId = 2;
            Thread.Sleep(2000);
            lane1.VoltageId = 3;
            Thread.Sleep(2000);
            lane1.VoltageId = 1;
            Thread.Sleep(2000);

            race1.End(true);*/

            //Start the discovery service
            DatagramListener discovery = new DatagramListener();
            discovery.DatagramReceived += new DatagramReceivedEventHandler(discovery_DatagramReceived);
            discovery.Start();

            ///Start the socket server
            TcpServer socketServer = new TcpServer();
            socketServer.Start();

            //Makes the main thread sleep forever.
            //When the main thread reach the end, the program end, 
            //even if the socket server threads are running
            Thread.Sleep(Timeout.Infinite);
        }

        static void discovery_DatagramReceived(object sender, DatagramReceivedEventArgs e)
        {
            var discoveryMsg = Encoding.UTF8.GetBytes(TrackController.getInstance().Name);
#if DEBUG
            Debug.Print(e.RemoteHost.ToString() + " -> " + new String(Encoding.UTF8.GetChars(e.Data)));
#endif
            using (Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                sck.SendTo(discoveryMsg, new IPEndPoint(e.RemoteHost.Address, 12345));
            }
        }
    }
}